package com.share.example.stock.schedule;

import com.alibaba.fastjson.JSON;
import com.share.common.utils.ThreadUtil;
import com.share.common.utils.CollectionUtil;
import com.share.common.utils.DateExtUtil;
import com.share.common.utils.DateUtil;
import com.share.example.stock.enums.IndicatorEnum;
import com.share.example.stock.model.db.ScheduleLog;
import com.share.example.stock.model.db.SectorSpot;
import com.share.example.stock.service.IScheduleLogService;
import com.share.example.stock.service.ISectorDetailService;
import com.share.example.stock.service.ISectorSpotService;
import com.share.example.stock.service.ITradeDateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;


/**
 * 板块和详情数据下载
 */

@Slf4j
@Component
public class S40_Down_stock_sector {
    private String className = this.getClass().getSimpleName();
    @Autowired
    private IScheduleLogService iScheduleLogService;
    @Autowired
    private ISectorSpotService iSectorSpotService;
    @Autowired
    private ITradeDateService iTradeDateService;
    @Autowired
    private ISectorDetailService iSectorDetailService;

    @PostConstruct
    @Scheduled(cron = "0 10 * * * ?")
    public void initSectorSpot() {
        iSectorSpotService.initSectorSpot();
    }

    // "0 18 23 * * ?" 每天晚上18点15执行一次
    @Scheduled(cron = "0 38/25 9-16,23 * * ?")
    public void down_sector() {
        Date date = new Date();
        //对时间再次细分
        int intDate = DateExtUtil.getTimeInt(date);
        if ((intDate > 93100 && intDate < 115000) || (intDate > 130500 && intDate < 152000) || (intDate > 230000 && intDate < 232500)) {
            //可以使用的时间
        } else {
            log.info("不满足时间直接退出");
            return;
        }

        //周日直接跳过
        if (!iTradeDateService.isTradeDay(date)) {
            log.info("非交易日直接退出");
            return;
        }

        String jobCode = className + "_" + "delete_min_date";

        //开始日志
        ScheduleLog insertLog = iScheduleLogService.insertLog(jobCode);

        //开始下载数据库
        ScheduleLog upLog = new ScheduleLog().setId(insertLog.getId());
        try {
            String message = "";
            IndicatorEnum[] values = IndicatorEnum.values();
            for (IndicatorEnum item : values) {
                String indicator = item.getCode();
                try {
                    List<SectorSpot> tmpList = iSectorSpotService.downSector(indicator);
                    message += indicator + "=" + (tmpList == null ? 0 : tmpList.size()) + ",";
                } catch (Exception e) {
                    log.error("下载失败indicator={}", indicator, e);
                }
            }
            upLog.setStatus("1");
            upLog.setRemark("数据信息:" + message);
        } catch (Exception e) {
            upLog.setExpMsg(e.getMessage());
            log.error("下载失败", e);
        }

        //更新日志
        iScheduleLogService.updateLogById(upLog);
    }


    /**
     * 成份股的数据不是很中国要
     */
    @Scheduled(cron = "0 40 9-16,22 * * ?")   //必须在30分钟之后运行
    public void down_sector_detail() {
        Date date = new Date();
        String strTradeDate = DateUtil.getDate(date);//拉取数据的交易日时间

        //周日直接跳过
        if (!iTradeDateService.isTradeDay(date)) {
            log.info("非交易日直接退出");
            return;
        }

        String jobCode = className + "_" + "down_sector_detail";

        //开始日志
        ScheduleLog insertLog = iScheduleLogService.insertLog(jobCode);

        try {
            //查询任务
            List<SectorSpot> list = iSectorSpotService.listLables();
            if (CollectionUtils.isEmpty(list)) {
                return;
            }

            int threadNum = 5;
            if ((list.size() / 10) < 0) {
                threadNum = 1;
            }


            //开启多线程
            List<Future<Map<String, List<String>>>> taskList = new LinkedList<>();

            List<List<SectorSpot>> partitionList = CollectionUtil.splitByThreadNum(list, threadNum);
            for (List<SectorSpot> tmpList : partitionList) {
                Future<Map<String, List<String>>> submit = ThreadUtil.submit(() -> iSectorDetailService.downSectorDetail(tmpList, strTradeDate));
                taskList.add(submit);
            }

            //获取多线执行的结果,并进行合并
            taskList.stream().forEach(e -> {
                try {
                    Map<String, List<String>> reMap = e.get();//阻塞当前进程
                    log.info("处理结果resMap={}", JSON.toJSONString(reMap));
                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
            });
        } catch (Exception e) {
            log.error("下载详情失败", e);
        }

        //结束日志
        ScheduleLog upLog = new ScheduleLog().setId(insertLog.getId()).setStatus("1");
        iScheduleLogService.updateLogById(upLog);
    }
}
